package cn.com.yusys.yusp.admin.sso;

import cn.com.yusys.yusp.uaa.domain.AuthUser;
import cn.com.yusys.yusp.uaa.security.SecurityDaoAuthenticationProvider;
import cn.com.yusys.yusp.uaa.security.credentialstrategy.AbstractCredentialStrategy;
import cn.com.yusys.yusp.uaa.security.credentialstrategy.PswWrongStrategyAbstract;
import cn.com.yusys.yusp.uaa.service.CredentialStrategyService;
import cn.com.yusys.yusp.uaa.service.util.BCRSAUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.context.SecurityContext;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.web.authentication.WebAuthenticationDetails;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.util.List;
import java.util.Map;

public class SSOSecurityDaoAuthenticationProvider extends SecurityDaoAuthenticationProvider {
    Logger logger = LoggerFactory.getLogger(SSOSecurityDaoAuthenticationProvider.class);
    @Resource
    private CredentialStrategyService credentialStrategyService;
    @Override
    public Boolean checks(AuthUser authUser, UserDetails userDetails, UsernamePasswordAuthenticationToken authentication) throws AuthenticationException {
        String username = authentication.getPrincipal().toString();
        Map<String, String> parameters = (Map)authentication.getDetails();
        String sysId = (String)parameters.get("sysId");
        if (sysId == null) {
            sysId = "";
            this.logger.info("Login user [{}] selected logical system id is null, request parameter: {}", username, parameters);
        }

        List<AbstractCredentialStrategy> credentialStrategy = this.credentialStrategyService.initCreStrategy(sysId);
        PswWrongStrategyAbstract pswWrongStrategy = (PswWrongStrategyAbstract)this.credentialStrategyService.getPswWrongStrategy(sysId);
        if(authentication.getCredentials() == null){
            this.logger.info("Authentication failed: user [{}] did not provide a password", username);
            if (pswWrongStrategy != null && pswWrongStrategy.isEnable()) {
                pswWrongStrategy.doCredentialStrategy(authUser, false);
            }

            throw new BadCredentialsException(this.messages.getMessage("150000", "wrong password"));
        }else {
            String password = authentication.getCredentials().toString();
            String presentedPassword = password;
            if ("2".equals(parameters.get("passwordType"))) {
                try {
                    presentedPassword = BCRSAUtil.decrypt(password);
                } catch (Exception var13) {
                    this.logger.error("BC decryption failed", var13);
                    throw new BadCredentialsException(this.messages.getMessage("AbstractUserDetailsAuthenticationProvider.badCredentials", "wrong password"));
                }
            }
            if ("true".equals(presentedPassword)) {
                SecurityContext securityContext = SecurityContextHolder.getContext();
                WebAuthenticationDetails webAuthenDetail = (WebAuthenticationDetails)securityContext.getAuthentication().getDetails();
                String currentIP = webAuthenDetail.getRemoteAddress();
                authUser.setCurrentIP(currentIP);
                return true;
            } else {
                return super.checks(authUser, userDetails, authentication);
            }
        }
    }
}
